package com.ccteam.fluidmusic.fluidmusic.common

import android.support.v4.media.MediaMetadataCompat
import androidx.annotation.GuardedBy

/**
 *
 * @author Xiaoc
 * @since 2021/1/3
 *
 * 播放列表管理器
 * 是一个单例类
 *
 * 管理着当前播放的播放列表内容
 * 使用列表 [List] 进行管理，其中索引index与 [ExoPlayer] 的内容 mediaSource 的索引index是相同的
 * 也就代表着可以通过当前播放列表中歌曲所在索引去进行播放对应歌曲
 *
 * 该单例类中内容线程安全（[@GuardedBy同步注释]）
 */
object PlaylistManager {

    private val mLock = Object()

    @GuardedBy("mLock")
    private var playlistCallback: PlaylistCallback? = null

    @GuardedBy("this")
    private val playlistQueue: MutableList<MediaMetadataCompat> = mutableListOf()

    @Synchronized
    fun add(position: Int, metadata: MediaMetadataCompat){
        playlistQueue.add(position,metadata)
        notifyCallback()
    }

    @Synchronized
    fun remove(position: Int){
        if(position < 0 || position >= playlistQueue.size){
            return
        }
        playlistQueue.removeAt(position)
        notifyCallback()
    }

    @Synchronized
    fun move(from: Int, to: Int){
        playlistQueue.add(to, playlistQueue.removeAt(from))
        notifyCallback()
    }

    @Synchronized
    fun replaceAll(metadataList: List<MediaMetadataCompat>){
        playlistQueue.clear()
        addAll(metadataList)
    }

    @Synchronized
    fun addAll(metadataList: List<MediaMetadataCompat>){
        playlistQueue.addAll(metadataList)
        notifyCallback()
    }

    fun setPlaylistCallback(callback: PlaylistCallback){
        synchronized(mLock){
            playlistCallback = callback
        }
    }

    fun clearPlaylistCallback(){
        playlistCallback = null
    }

    fun getItem(index: Int): MediaMetadataCompat{
        if(index < 0 || index >= playlistQueue.size){
            return METADATA_NOTHING_PLAYING
        }
        return playlistQueue[index]
    }

    fun getItems() = playlistQueue

    private fun notifyCallback(){
        playlistCallback?.playlistQueueChanged(playlistQueue)
    }

    /**
     * 播放列表回调接口
     */
    interface PlaylistCallback{

        /**
         * 当播放列表内容发生变化时回调
         */
        fun playlistQueueChanged(playlistQueue: List<MediaMetadataCompat>)
    }
}